<?php
class Zfb_Acl extends Zend_Acl
{
	protected $_roleClass = 'Zfb_Acl_Role';
	protected $_resourceClass = 'Zfb_Acl_Resource';
	/**
	 * Singleton instace
	 * @var Zfb_Acl
	 */
	protected static $_instance;
	/**
	 * Singleton design pattern
	 */
	protected function __contruct()
	{
		$this->_initAcl();
	}
	/**
	 * Singleton design pattern
	 */
	protected function __clone(){}
	/**
	 * Singleton design pattern
	 * @return Zfb_Acl
	 */
	public static function getInstance()
	{
		if (null === self::$_instance) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}
	
	/**
	 * Initializes ACL
	 * @return void
	 */
	protected function _initAcl()
	{
		$this->_initResources();
		$this->_initRoles();
		$this->_initRules();
	}
	
	/**
	 * Initializes ACL resources
	 * @return void
	 */
	protected function _initResources()
	{
		$model = new Zfb_Acl_Model_Resources();
		foreach($model->fetchAll() as $resource){
			$this->addResource(new $this->_resourceClass($resource));
		}
	}
	
	/**
	 * Initializes ACL roles
	 * @return void
	 */
	protected function _initRoles()
	{
		$model = new Zfb_Acl_Model_Roles();
		foreach($model->fetchAll() as $role){
			$this->addRole(new $this->_roleClass($role));
		}
	}
	
	/**
	 * Initializes ACL privleges
	 * @return void
	 */
	protected function _initPrivleges()
	{
		$model = new Zfb_Acl_Model_Privleges();
		$data = $model->getPrivlegeRules();
		$this->_processPrivleges($data);	
	}
	/**
	 * Takes array of db rows and uses it to create ACL rules 
	 * @param array $data db rows with joined resource and roles
	 * @return void
	 */
	protected function _processPrivleges(array $data)
	{
		foreach($data as $rule){
			$resourceData = new stdClass();
			$resourceData->id = $rule->resource_id;
			$resourceData->module = $rule->module;
			$resourceData->controller = $rule->controller;
			$resourceData->action = $rule->action;
			$resource = new $this->_resourceClass($resourceData);
			$roleData->id = $rule->role_id;
			$roleData->name = $role->name;
			$role = new $this->_roleClass($roleData);
			$action = ($rule->allow == 1?'allow':'deny');
			$this->$action($role, $resource);
		}
	}
}